package gov.fnal.xpath2ldap;

import java.util.List;
import java.util.Stack;
import java.util.LinkedHashMap;
import java.io.FileOutputStream;

import org.w3c.dom.*;
import org.apache.commons.cli.CommandLine;

public class XQueryLDAPEvaluator {
    XMLAdapter xmler;
    LPathSearch searcher;
    DSMLTransform xformer;
    boolean evaluate_expression=false;
    boolean write_source_xml=true;
    protected String xqueryfile;
    public static final String LF = "\n";
    public static final String DN = "dn";

    public XQueryLDAPEvaluator(CommandLine cmdline) {
        xmler = new XMLAdapter(cmdline);
        searcher = new LPathSearch(xmler);
        xformer = new DSMLTransform(xmler);
        String output = xmler.getCommandLine().getOptionValue(XQuerySearchOptions.OUTPUT, XQuerySearchOptions.OUTPUT_DEFAULT);
        write_source_xml = XQuerySearchOptions.OUTPUT_SOURCE_XML.equals(output);
        String action = xmler.getCommandLine().getOptionValue(XQuerySearchOptions.ACTION, XQuerySearchOptions.ACTION_DEFAULT);
        evaluate_expression = XQuerySearchOptions.ACTION_EVALUATE.equals(action);
        xqueryfile = xmler.getCommandLine().getOptionValue(XQuerySearchOptions.XQUERYFILE);
    }

    public XQueryLDAPEvaluator(String hostname, int port) {
        xmler = new XMLAdapter(hostname, port);
        searcher = new LPathSearch(xmler);
        xformer = new DSMLTransform(xmler);
    }

    public String search(String expr) {

        boolean from_file=false;
        boolean write_file=false;
        if(!from_file)
            try {

                XqueryxStaxParser runparser = new XqueryxStaxParser();

                String xqueryx_str = runparser.parseXpathToXqueryX(expr);
                List<String> lpathList = runparser.parseXqueryX(xqueryx_str);
                List<Pair<String, Boolean>> combined = runparser.combineOperations(lpathList);
                List<String> boolcomb = runparser.combineBooleans(combined);
                List<String> lFullPaths = runparser.getFullPaths(boolcomb);
                Pair<Document, LinkedHashMap<String, Stack<String>>> fromLPathSearch;
                fromLPathSearch = searcher.search(lFullPaths);
                Document fromldap = xformer.xformDSMLToStructuredXML(fromLPathSearch);
                if(write_file) {
                    try {
                        String tmpdir = System.getProperty("xpathsearch.home", System.getProperty("user.home")) + "/tmp";
                        FileOutputStream fos = new FileOutputStream(tmpdir + "/fromsearch.xml");
                        XMLAdapter.serialize(fromldap, fos);
                        fos.flush();
                        fos.close();
                    } catch (Exception e) {
                        System.err.println("Could not serialize result " + e);
                    }
                }
                if(write_source_xml) {
                    try {
                        XMLAdapter.serialize(fromldap, System.out);
                    } catch (Exception e) {
                        System.err.println("Could not serialize result " + e);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        if(evaluate_expression) {
            try {
                //String xquery_arg = (xqueryfile==null) ? "-qs:"+expr : "-q:"+xqueryfile;
                net.sf.saxon.Query.main(new String[]{"-s:/home/tdh/testing/osg-discovery-0.5-r199/tmp/fromsearch.xml", "-qs:"+expr, "!method=text", "vo=engage"});
            } catch (Exception e) {
                System.out.println("Saxon parser failed.");
                e.printStackTrace();
            }
        }
        return "";
    }
}